#ifndef __GLF_INPUTMANAGER_H_INCLUDED__
#define __GLF_INPUTMANAGER_H_INCLUDED__

#include <glf/config.h>
#include <glf/core/event.h>
#include <glf/input/inputDevice.h>

#include <set>

namespace glf 
{
	//GamepadType
	enum GamepadType {
		GAMEPADTYPE_XBOX360,
		GAMEPADTYPE_PS3,
		GAMEPADTYPE_WII,
		GAMEPADTYPE_GAMECUBE,
		GAMEPADTYPE_DS,
		GAMEPADTYPE_IPHONE,
		GAMEPADTYPE_KD,
		GAMEPADTYPE_SDL,
		GAMEPADTYPE_PSP2,

		//GAMEPADTYPE_PS2,
		//GAMEPADTYPE_XBOX,

		GAMEPADTYPE_COUNT
	};

	//InputManager
	class InputManager 
		:	public EventReceiver 
	{

		friend class InputDevice;

	public:
		InputManager();
		virtual ~InputManager();

	public:
		
		void UpdateFrame();

		void EnableAccelerometer(bool isEnabled, float frequency);
		bool EnableGyro(bool isEnabled, float frequency);
		bool IsAccelerometerEnabled() const;
		void EnableSensor(bool isEnabled);

		Keyboard& GetKeyboard(uint idx);
		size_t GetKeyboardCount() const;
		size_t GetKeyboardIndex(const InputDevice *inputDevice);
		
		Mouse& GetMouse(uint idx);
		size_t GetMouseCount() const;
		size_t GetMouseIndex(const InputDevice *inputDevice);

		Gamepad& GetGamepad(uint idx);
		size_t GetGamepadCount() const;
		size_t GetGamepadIndex(const InputDevice *inputDevice);		

		void EmulateGamepadWin32(GamepadType type);
		
		bool OnEvent(const CoreEvent& evt);
		
		void StartDuoProtocol(bool isThreaded);

	private:
		void AddUpdatedDevice(InputDevice *device);

		Mutex mMutex;
		std::set<InputDevice *> mUpdatedDevices;

		GLF_DECLARE_IMPL(64 * 1024)
	};

} //namespace glf

#endif
